﻿using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using Autofac.Integration.Mvc;
using RTW.Utils.Ioc;

namespace RTW.Utils.Utils
{

        public static class IocUril
        {
            private static IContainer container;

            //程序启动时执行一次。
            public static void InitIocContainer()
            {
            var builder = new ContainerBuilder();
            //注册所有服务


            //获取IAutoInject的Type
            var baseType = typeof(IAutoInject);
            //获取所有程序集
            //var assemblies = System.Web.Compilation.BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
            var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToArray();
            //自动注册类实例
            builder.RegisterAssemblyTypes(assemblies).Where(b => b.GetInterfaces().
            Any(c => c == baseType && b != baseType)).InstancePerLifetimeScope();
            //.AsImplementedInterfaces()

            //// RegisterType方式：
            //builder.RegisterType<InjectionTestService>().AsSelf().InstancePerDependency();
            //// Register方式：
            //builder.Register(c => new InjectionTestService()).AsSelf().InstancePerDependency();

            //// 自动注入的方式，不需要知道具体类的名称

            ///* BuildManager.GetReferencedAssemblies()
            // * 程序集的集合，包含 Web.config 文件的 assemblies 元素中指定的程序集、
            // * 从 App_Code 目录中的自定义代码生成的程序集以及其他顶级文件夹中的程序集。
            // */

            //// 获取包含继承了IService接口类的程序集
            //var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>()
            //    .Where(
            //        assembly =>
            //            assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) !=
            //            null
            //    );

            //// RegisterAssemblyTypes 注册程序集
            //var enumerable = assemblies as Assembly[] ?? assemblies.ToArray();
            //if (enumerable.Any())
            //{
            //    builder.RegisterAssemblyTypes(enumerable)
            //        .Where(type => type.GetInterfaces().Contains(typeof(IService))).AsSelf().InstancePerDependency();
            //}
            // Register 方式指定具体类
            //builder.Register(c => new InjectionTestService()).As<IService>().InstancePerDependency();

            //// RegisterType 方式指定具体类
            //builder.RegisterType<InjectionTestService>().As<IService>().InstancePerDependency();

            //// 自动注册的方式

            //// 获取包含继承了IService接口类的程序集
            //var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>()
            //    .Where(
            //        assembly =>
            //            assembly.GetTypes().FirstOrDefault(type => type.GetInterfaces().Contains(typeof(IService))) !=
            //            null
            //    );

            //// RegisterAssemblyTypes 注册程序集
            //var enumerable = assemblies as Assembly[] ?? assemblies.ToArray();
            //if (enumerable.Any())
            //{
            //    builder.RegisterAssemblyTypes(enumerable)
            //        .Where(type => type.GetInterfaces().Contains(typeof(IService))).AsImplementedInterfaces().InstancePerDependency();
            //}
          //  typeof(IMessage).Assembly.GetTypes()
          //.Where(t => t.GetInterfaces().Contains(typeof(IMessage)))
          //.ForEach(type =>
          //{
          //      // 注册type
          //  });

            //自动注册控制器所有的Controller
            builder.RegisterControllers(assemblies);
            container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }

        //获取具体的实例
        public static T Resolve<T>(string key = "") where T : class
        {
            if (string.IsNullOrEmpty(key))
            {
                return container.Resolve<T>();
            }
            return container.ResolveKeyed<T>(key);
        }


        //获取具体的实例
        public static object Resolve(Type type,string key = "")
        {
            if (string.IsNullOrEmpty(key))
            {
                return container.Resolve(type);
            }
            return container.ResolveKeyed(key, type);
        }
    }

}
